home *** CD-ROM | disk | FTP | other *** search
/ Informática Multimedia 1995 April / Informatica Multimedia CD - Epimundo.iso / DOS / FILEVIEW / VIEW.ZIP / VIEW.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-06-10  |  9.7 KB  |  471 lines

  1.  
  2. ; A86 source code for VIEW.COM v2.1
  3.  
  4. BUFFER        EQU  0600        ;allow 2k for code + data + stack
  5. HALF_READ    EQU  07C00        ;31k = half read buffer
  6. FULL_READ    EQU  HALF_READ + HALF_READ
  7. BUFFER_TOP    EQU  BUFFER + FULL_READ
  8. SHIFT        EQU  16            ;right arrow key shift
  9.  
  10.         ORG 0100
  11.         JMP SHORT START
  12.  
  13. VIDEO_ADDR    DW  'DD'
  14. VIDEO_SEG    DW  0B800
  15. PLACE_MARK    DW  BUFFER
  16.  
  17. SCR_ROWS    DW  0
  18. CGA_MODE    DB  0
  19.  
  20. NO_FILE        DB  'No File$'
  21. NO_MEMORY    DB  'Out of RAM$'
  22.  
  23. START:        CLD
  24.         CMP SP, 65530        ;FFFE = 65,534
  25.         JAE PARSE
  26.         MOV DX, OFFSET NO_MEMORY
  27. QUIT:        MOV AH, 9
  28.         INT 021
  29.         INT 020
  30.  
  31. PARSE:        MOV SI, 081          ;point to command line parameters
  32. L1:        LODSB             ;load into AL, increase SI
  33.         CMP AL, 020          ;space?
  34.         JE L1             ;then skip
  35.         CMP AL, 0D        ;carriage return?
  36.         JE FILE_ERROR
  37.         CMP AL, '/'          ;possible delimiter
  38.         JNE OPEN_FILE
  39.         LODSB
  40.         AND AL, 0DF
  41.         MOV W[PATCH], 020CD    ;modify code - INT 020
  42.         CMP AL, 'R'        ;redirect
  43.         JNE FILE_ERROR
  44.  
  45.         XOR BX, BX
  46.         MOV AH, 045        ;duplicate file handle
  47.         INT 021
  48.         MOV W[FILE_HANDLE], AX    ;save HANDLE 
  49.         MOV AH, 03E        ;close file
  50.         INT 021
  51.         MOV BX, 2
  52.         MOV AH, 045
  53.         INT 021
  54.         JMP SHORT A1
  55.  
  56. FILE_ERROR:    MOV DX, OFFSET NO_FILE
  57.         JMP QUIT  
  58.  
  59. OPEN_FILE:    MOV DX, SI        ;point DX at string
  60.         DEC DX            ;remember SI was advanced
  61. L2:        LODSB
  62.         CMP AL, 0D        ;CR end of line?
  63.         JE  PUT_ZERO
  64.         CMP AL, 020        ;space between parameters?
  65.         JNE L2
  66. PUT_ZERO:    MOV B[SI-1], 0        ;end string with zero, for Asciiz
  67.         MOV AX, 03D00        ;OPEN file for reading
  68.         INT 021
  69.         JC  FILE_ERROR
  70.         MOV W[FILE_HANDLE], AX
  71.  
  72. A1:        MOV AH, 0F        ;video mode in AL
  73.         INT 010
  74.         CMP AL, 7        ;monochrome 80 x 25
  75.         JE  VIDEO_INFO
  76.         CMP AL, 3        ;color text 40 x 25 or 80 x 25
  77.         JBE VIDEO_INFO
  78.         MOV AX, 03        ;force color text if necessary
  79.         INT 010
  80. VIDEO_INFO:    MOV AX, 040        ;BIOS data area
  81.         MOV ES, AX
  82.         ES  MOV AX, W[063]        ;display card
  83.         MOV W[PORT_ADDRESS], AX
  84.         TEST AL, 020        ;03B4 = mono   03D4 = color
  85.         JZ  COLOR        ; 1011 0100     1101 0100
  86.         MOV VIDEO_SEG, 0B000    ;mono segment address
  87.         JMP SHORT NO_CGA
  88. COLOR:        MOV AH, 012        ;returns EGA info
  89.         MOV BL, 010
  90.         INT 010
  91.         CMP BL, 010        ;if unchanged, then CGA
  92.         JNE NO_CGA
  93.         MOV CGA_MODE, 1
  94. NO_CGA:        ES  MOV AX, W[04E]        ;offset to current page
  95.         MOV VIDEO_ADDR, AX
  96.         MOV AH, 0F
  97.         INT 010            ;page in BH, AH = screen width
  98.         MOV B[PAGE_NUM+1], BH
  99.         MOV B[SCR_COLUMNS], AH
  100.         ES  MOV AL, B[084]        ;character rows on screen
  101.         INC AL
  102.         MOV B[SCR_ROWS], AL
  103.         PUSH CS
  104.         POP ES
  105.         
  106.         MOV AH, 8        ;read screen char (pg in BH)
  107.         INT 010
  108.         MOV B[ATTRIBUTE], AH
  109.         MOV AH, 03        ;find cursor function
  110.         INT 010            ;CH start - CL stop - scan line
  111.         MOV W[USER_CURSOR+1], CX
  112.         MOV AH, 01        ;these 3 lines to remove cursor
  113.         MOV CH, 020        ;blank cursor code
  114.         INT 010
  115.  
  116.         MOV DX, OFFSET ERROR_HANDLE
  117.         MOV AX, 02523
  118.         INT 021
  119.         MOV B[INPUT_COUNT], 0    ;initialize data area at end
  120.         MOV W[LOW_OFFSET], 1
  121.         CALL HOME        ;set SI = BUFFER
  122. A5:        LEA BP, BLANK_SCREEN
  123.  
  124. DISPLAY:    CALL SHOW_PAGE
  125. GET_ASCII:    MOV AH, 8        ;get key
  126.         INT 021
  127.         CMP AL, 01B        ;ESC
  128.         JE  ERROR_HANDLE
  129.         CMP AL, '*'
  130.         JNE GET_SCAN
  131.         XOR B[WORDSTAR+1], 080    ;AND with 07F to turn off high bit
  132.         JMP A5
  133. GET_SCAN:    CMP AL, 0
  134.         JNZ GET_ASCII
  135.         MOV AH, 8
  136.         INT 021
  137.         SUB AL, 047        ;ready for key table
  138.         JB  GET_ASCII
  139.         CMP AL, 0C
  140.         JA  GET_ASCII
  141.         CBW
  142.         SHL AX, 1        ;double it for WORD table
  143.         MOV BX, AX
  144.         MOV SI, W[PLACE_MARK]
  145.         LEA BP, BLANK_SCREEN
  146.         CALL KEY_TABLE[BX]    ;process each key press
  147.         MOV W[PLACE_MARK], SI
  148.         JMP DISPLAY
  149.  
  150. ERROR_HANDLE:
  151. USER_CURSOR:    MOV CX, 0B0C        ; (self modify) restore normal cursor
  152.         MOV AH, 1       
  153.         INT 010
  154. PATCH:        MOV BX, W[FILE_HANDLE]    ; (self modify) make INT 020 for 
  155.         MOV AH, 03E        ;    redirection, else CLOSE file
  156.         INT 021
  157.         INT 020
  158.  
  159. KEY_TABLE    DW  HOME, UP, PGUP, NONE, LEFT, NONE, RIGHT, NONE
  160.         DW  ENDY, DOWN, PGDN, DO_SEARCH, SEARCH_AGAIN
  161.                     ;ins         del
  162.  
  163. HOME:        XOR BX, BX
  164.         MOV AX, W[LOW_OFFSET]
  165.         OR  AX, W[HIGH_OFFSET]
  166.         MOV W[LOW_OFFSET], BX
  167.         MOV W[HIGH_OFFSET], BX
  168.         MOV W[SHIFT_RIGHT], BX
  169.         MOV SI, BUFFER
  170.         JZ  RET
  171.         MOV DX, BUFFER
  172.         MOV CX, FULL_READ
  173.         CALL READ_FILE
  174.         RET
  175.  
  176. UP:        CALL BACKUP
  177.         JC  NONE
  178.         MOV BP, OFFSET NEW_UP
  179. UP2:        CALL BACKUP
  180. B1:        CALL BACKUP        ;step back with SI
  181.         JC  RET 
  182.         CMP AL, 0A
  183.         JNE B1            ;go till find LF
  184.         CALL FORWARD
  185.         RET
  186.  
  187. ENDY:        MOV SI, W[END_BYTE]
  188.         CMP SI, BUFFER_TOP
  189.         JBE PGUP
  190.         CALL FORWARD2
  191.         JMP ENDY
  192.  
  193. PGUP:        MOV CX, W[SCR_ROWS]
  194.         CALL BACKUP
  195.         JC  NONE
  196. B2:        CALL UP2
  197.         LOOP B2
  198.         RET
  199.  
  200. LEFT:        CMP W[SHIFT_RIGHT], 0
  201.         MOV W[SHIFT_RIGHT], 0
  202.         JNZ RET
  203. NONE:        POP AX            ;get rid of RET address from stack
  204.         JMP GET_ASCII
  205.  
  206. RIGHT:        MOV AL, SHIFT
  207.         CBW
  208.         ADD W[SHIFT_RIGHT], AX
  209.         RET
  210.  
  211. DOWN:        MOV BP, OFFSET NEW_DOWN
  212. DOWN2:        CALL FORWARD
  213.         JC  RET
  214.         CMP AL, 0A
  215.         JNE DOWN2
  216.         RET
  217.  
  218. PGDN:        MOV CX, W[SCR_ROWS]
  219. B4:        CALL DOWN2
  220.         LOOP B4
  221.         JC  NONE
  222.         RET
  223.  
  224. SHOW_PAGE:    PUSH ES
  225.         MOV SI, W[PLACE_MARK]
  226.         MOV ES, W[VIDEO_SEG]
  227.         CALL BP            ;blank screen, scroll up or down
  228.         MOV AL, B[SCR_COLUMNS]
  229.         CBW
  230.         ADD AX, W[SHIFT_RIGHT]
  231.         MOV W[TOTAL_SHIFT], AX
  232.         XOR DL, DL
  233. B7:        XOR BX, BX
  234.         MOV AL, B[SCR_COLUMNS]
  235.         MUL DL
  236.         SHL AX, 1
  237.         MOV DI, AX
  238.         ADD DI, W[VIDEO_ADDR]
  239. NEXT_LINES:    CALL FORWARD        ;get char in AL, advance SI
  240.         JC  END_PAGE
  241. WORDSTAR:    AND AL, 0FF        ;flipflop 0FF & 07F, turn off high bit
  242.         CMP AL, 0D        ;CR
  243.         JE  NEXT_LINES
  244.         CMP AL, 0A        ;LF
  245.         JE  NEW_LINE
  246.         CMP AL, 09        ;TAB
  247.         JE  TAB
  248.         MOV CX, 1
  249. C2:        CMP BX, W[SHIFT_RIGHT]
  250.         JB  C6
  251.         CMP BX, W[TOTAL_SHIFT]
  252.         JAE C6
  253.         MOV AH, B[ATTRIBUTE]
  254.         CMP SI, W[SEARCH_MARK]
  255.         IF E XOR AH, 0F7    ;inverse attribute, blink
  256.         CMP B[CGA_MODE], 0
  257.         JZ  C5
  258.         PUSH BX
  259.         PUSH DX
  260.         MOV BX, AX
  261.         MOV DX, W[PORT_ADDRESS]
  262.         ADD DX, 6        ;status register
  263. HORIZ_RETRACE:    IN  AL, DX
  264.         SHR AL, 1
  265.         JC  HORIZ_RETRACE
  266.         CLI            ;Disable interupts.
  267. WAITER:        IN  AL, DX
  268.         SHR AL, 1
  269.         JNC WAITER
  270.         MOV AX, BX
  271.         STOSW
  272.         STI            ;Enable interupts.
  273.         POP DX
  274.         POP BX
  275.         JMP SHORT C6
  276. C5:        STOSW
  277. C6:        INC BX
  278.         LOOP C2
  279.         JMP NEXT_LINES
  280. TAB:        MOV AX, BX        ;adjust column counter
  281.         AND AX, 07        ;get bottom three bits
  282.         MOV CX, 08        ;adjust
  283.         SUB CX, AX
  284.         MOV AL, 020        ;pad spaces
  285.         JMP C2
  286. NEW_LINE:    INC DL
  287.         CMP DL, B[SCR_ROWS]
  288.         JB  B7
  289. END_PAGE:    POP ES
  290.         RET
  291.  
  292. FORWARD:    CMP SI, W[END_BYTE]
  293.         JAE D2
  294.         CMP SI, BUFFER_TOP
  295.         JB  D1
  296. FORWARD2:    PUSH CX
  297.         PUSH DX
  298.         PUSH DI
  299.         PUSH ES
  300.         PUSH DS
  301.         POP ES
  302.         MOV SI, BUFFER + HALF_READ
  303.         MOV DI, BUFFER
  304.         MOV CX, HALF_READ
  305.         SUB W[PLACE_MARK], CX
  306.         REP MOVSB
  307.         MOV SI, DI
  308.         ADD W[LOW_OFFSET], FULL_READ
  309.         ADC W[HIGH_OFFSET], 0
  310.         MOV DX, BUFFER + HALF_READ
  311.         MOV CX, HALF_READ
  312.         CALL READ_FILE
  313.         SUB W[LOW_OFFSET], HALF_READ
  314.         SBB W[HIGH_OFFSET], 0
  315.         POP ES
  316.         POP DI
  317.         POP DX
  318.         POP CX
  319.         JMP FORWARD
  320. D1:        LODSB
  321. D2:        CMC            ;Complement carry flag.
  322.         RET
  323.  
  324. BACKUP:        CMP SI, BUFFER
  325.         JA  D3
  326.         MOV AX, W[LOW_OFFSET]
  327.         OR  AX, W[HIGH_OFFSET]
  328.         JZ  D4
  329.         PUSH CX
  330.         PUSH DX
  331.         MOV SI, BUFFER
  332.         MOV DI, BUFFER + HALF_READ
  333.         MOV CX, HALF_READ
  334.         ADD W[PLACE_MARK], CX
  335.         REP MOVSB
  336.         SUB W[LOW_OFFSET], HALF_READ
  337.         SBB W[HIGH_OFFSET], 0
  338.         MOV DX, BUFFER
  339.         MOV CX, HALF_READ
  340.         CALL READ_FILE
  341.         POP DX
  342.         POP CX
  343. D3:        DEC SI
  344.         MOV AL, B[SI]
  345.         CLC                 ;Clear the carry flag.
  346.         RET
  347. D4:        STC
  348.         RET
  349.  
  350. READ_FILE:    PUSH AX
  351.         PUSH BX
  352.         PUSH CX
  353.         PUSH DX
  354.         MOV W[SEARCH_MARK], 0
  355.         MOV W[END_BYTE], 0FFFF
  356.         MOV DX, W[LOW_OFFSET]    ;CX:DX offset in file (begin 0)
  357.         MOV CX, W[HIGH_OFFSET]
  358.         MOV BX, W[FILE_HANDLE]
  359.         MOV AX, 04200        ;set file read pointer
  360.         INT 021
  361.         POP DX
  362.         POP CX
  363.         MOV AH, 03F        ;read file
  364.         INT 021
  365.         JNC D5
  366.         XOR AX, AX
  367. D5:        CMP AX, CX        ;bytes read
  368.         JE  D6
  369.         ADD AX, DX
  370.         MOV W[END_BYTE], AX
  371. D6:        POP BX
  372.         POP AX
  373.         RET
  374.  
  375. BLANK_SCREEN:    MOV AX, 0600
  376.         JMP SHORT D8
  377.  
  378. NEW_UP:        MOV AH, 07
  379.         JMP SHORT D7
  380.  
  381. NEW_DOWN:    MOV AH, 06
  382. D7:        MOV AL, 1
  383. D8:        XOR CX, CX        ;top left corner 0, 0
  384.         MOV DL, B[SCR_COLUMNS]
  385.         DEC DL
  386.         MOV DH, B[SCR_ROWS]    ;DX lower right corner 24, 79
  387.         DEC DH
  388.         MOV BH, B[ATTRIBUTE]
  389.         INT 010
  390.         RET
  391.  
  392. DO_SEARCH:    MOV AX, 0920        ;write without moving the cursor
  393. PAGE_NUM:    MOV BH, 0        ;(self modify) active display page 
  394.         MOV BL, B[ATTRIBUTE]
  395.         MOV CX, 60        ;# of chars for buffer is 60
  396.         INT 010
  397.         MOV AX, 0E BY '?'    ;TTY write of question mark
  398.         INT 010
  399.         MOV CX, 010C        ;block cursor
  400.         MOV AH, 1       
  401.         INT 010
  402.  
  403.         MOV W[INPUT_SIZE], 61    ;INPUT_SIZE = 61, INPUT_COUNT = 0
  404.         MOV DX, OFFSET INPUT_SIZE
  405.         MOV AH, 0A        ;get buffered keyboard input
  406.         INT 021
  407.         MOV AH, 01        ;these 3 lines to remove cursor
  408.         MOV CH, 020        ;blank cursor code
  409.         INT 010
  410.         CMP B[INPUT_COUNT], 0
  411.         JZ  RET
  412.         CALL HOME        ;SI at buffer
  413.         JMP SHORT SET_UP
  414.  
  415. SEARCH_AGAIN:    CMP B[INPUT_COUNT], 0
  416.         IF Z JMP NONE
  417.         CALL DOWN2
  418.         CALL DOWN2
  419.         JMP SHORT SET_UP
  420.  
  421. READ_MORE:    CMP W[END_BYTE], 0FFFF    ;middle of file?
  422.         JNE SEARCH_DONE
  423.         CALL FORWARD2
  424.         DEC SI
  425. SET_UP:        MOV DI, SI        ;DI in file
  426.         MOV SI, OFFSET INPUT    ;SI at search entry
  427.         LODSB            ;AL first character for search
  428.         MOV CX, W[END_BYTE]
  429.         CMP CX, BUFFER_TOP
  430.         IF A MOV CX, BUFFER_TOP
  431.         SUB CX, DI        ;CX bytes to search
  432.  
  433. FIND_MATCH:    REPNE SCASB
  434.         JCXZ READ_MORE
  435.         PUSH CX            ;first character matches
  436.         PUSH DI
  437.         PUSH SI
  438.         MOV CL, B[INPUT_COUNT]
  439.         XOR CH, CH
  440.         DEC CL
  441.         REPE CMPSB        ;compare with search input
  442.         POP SI
  443.         POP DI
  444.         POP CX
  445.         JNE FIND_MATCH
  446.         MOV W[SEARCH_MARK], DI    ;record position
  447. SEARCH_DONE:    MOV SI, DI
  448.         CALL UP2
  449.         CALL UP2
  450. LAST:        RET
  451.  
  452.    DATA SEGMENT
  453.     ORG OFFSET LAST+1
  454.  
  455. ATTRIBUTE    DB  ?
  456. SCR_COLUMNS    DB  ?
  457. PORT_ADDRESS    DW  ?
  458. LOW_OFFSET    DW  ?
  459. HIGH_OFFSET    DW  ?
  460. SHIFT_RIGHT    DW  ?
  461. TOTAL_SHIFT    DW  ?
  462. FILE_HANDLE    DW  ?
  463. END_BYTE    DW  ?
  464. SEARCH_MARK    DW  ?
  465.  
  466. INPUT_SIZE    DB  ?        ;buffered keyboard input, 1st byte buffer size
  467. INPUT_COUNT    DB  ?        ;next byte = number of characters read
  468. INPUT        DB  61 DUP ?    ;buffer for 60 characters (plus CR)
  469.  
  470.    DATA ENDS
  471.